package com.iot08.admin.service;

import com.iot08.admin.service.page.PageableImpl;
import com.iot08.admin.tools.DESEncryptTools;
import com.iot08.admin.utils.buckettool.BaseBucketTool;
import com.iot08.common.constant.Const;
import com.iot08.common.entity.admin.ChannelArea;
import com.iot08.common.entity.admin.SysUser;
import com.iot08.common.service.base.BaseAdminService;
import com.iot08.common.utils.DateUtil;
import com.iot08.common.utils.StringUtil;
import com.iot08.common.utils.UUIDGenerator;
import com.iot08.admin.service.page.PageVO;
import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.Sort;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.core.query.Update;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import java.io.IOException;
import java.util.Date;
import java.util.List;

/**
 * @version 1.0
 * @Description:
 * @author: Rock
 * @time: 2020/10/12 11:20
 */
@Service
public class UserService extends BaseAdminService<SysUser> {

    @Resource
    private RoleService roleService;
    @Resource
    private ChannelAffiliationService channelAffiliationService;
    @Resource
    private BaseBucketTool baseBucketTool;
    @Resource
    private OperationService operationService;
    @Resource
    private ChannelAreaService channelAreaService;



    /**
     * @param [account, password]
     * @Description: 根据账号密码查询用户
     * @time: 2020/8/20 15:48
     * @author: Rock
     * @version 1.0
     */
    public SysUser findUserByAccountAndPassword(String account, String password) {
        Criteria criteria = Criteria.where("account").is(account).and("password").is(password).and("deleted").is(0);
        SysUser user = mongoTemplate.findOne(new Query(criteria), SysUser.class);
        userInfoHandle(user);
        return user;
    }

    /**
     * @param [account, ip]
     * @Description: 根据账号更新登录时间和登录ip
     * @time: 2020/8/20 15:48
     * @author: Rock
     * @version 1.0
     */
    public void updateLastLoginTime(String id, Date oldLastLoginTime, String ip) {
        Query query = new Query(Criteria.where("_id").is(id));
        Update update = new Update().set("last_login_time", new Date()).set("ip", ip);
        if (oldLastLoginTime == null) {
            update.set("old_last_login_time", new Date());
        } else {
            update.set("old_last_login_time", oldLastLoginTime);
        }
        mongoTemplate.updateFirst(query, update, SysUser.class);
    }

    /**
     * @param page
     * @param type
     * @param status
     * @param roleId
     * @time: 2020/12/17 10:26
     * @author: Rock
     * @version 1.0
     */
    public Page<SysUser> list(PageVO page, Integer type, Integer status, String roleId) {
        PageableImpl pageable = new PageableImpl();
        page.setSort(Sort.by(Sort.Order.desc("create_time")));
        pageable.setPage(page);

        Criteria criteria = new Criteria().and("deleted").is(0).and("channel_area_id").exists(false);
        ;
        if (StringUtils.isNotEmpty(page.getSearchValue())) {
            criteria.and("account").regex(".*?" + page.getSearchValue() + ".*?", "i");
        }
        if (type != null) {
            criteria.and("type").is(type);
        }
        if (status != null) {
            criteria.and("status").is(status);
        }
        if (StringUtil.isNotBlank(roleId)) {
            criteria.and("role_id").is(roleId);
        }
        Query query = new Query().addCriteria(criteria);
        long count = mongoTemplate.count(query, SysUser.class);
        page.setTotalResult((int) count);
        List<SysUser> list = mongoTemplate.find(query.with(pageable), SysUser.class);
        for (SysUser u : list) {
            userInfoHandle(u);
        }
        Page<SysUser> result = new PageImpl<SysUser>(list, pageable, count);
        return result;
    }

    /**
     * @param [page]
     * @Description: 后台账号管理列表
     * @time: 2020/8/20 15:51
     * @author: Rock
     * @version 1.0
     */
    public Page<SysUser> listFix(PageVO page, Integer status, String roleId,
                                 List<String> channelAreaIdList, Integer userType, int userAreaLevel) {
        PageableImpl pageable = new PageableImpl();
        page.setSort(Sort.by(Sort.Order.desc("create_time")));
        pageable.setPage(page);

        Criteria criteria = new Criteria().and("deleted").is(0);
        if (StringUtils.isNotEmpty(page.getSearchValue())) {
            criteria.and("account").regex(".*?" + page.getSearchValue() + ".*?", "i");
        }
        if (status != null) {
            criteria.and("status").is(status);
        }
        if (StringUtil.isNotBlank(roleId)) {
            criteria.and("role_id").is(roleId);
        }
        if (Const.INT_1.equals(userType)) {
            //渠道账号
            criteria.and("channel_area_id").in(channelAreaIdList);
        } else {
            //系统账号
            criteria.and("channel_area_id").exists(true);
        }
        Query query = new Query().addCriteria(criteria);
        long count = mongoTemplate.count(query, SysUser.class);
        page.setTotalResult((int) count);
        List<SysUser> list = mongoTemplate.find(query.with(pageable), SysUser.class);
        for (SysUser u : list) {
            userInfoHandle(u);
            channelAreaService.showNameHandle(u.getChannelArea(), userAreaLevel);
        }
        Page<SysUser> result = new PageImpl<SysUser>(list, pageable, count);
        return result;
    }

    /**
     * @Description: 保存
     * @time: 2020/8/20 17:13
     * @author: Rock
     * @version 1.0
     */
    public void save(SysUser user, MultipartFile file, SysUser u, String ip) throws IOException {
        if (user != null) {
            if (file != null && !file.isEmpty()) {
                //上传头像处理
                String imgUrl = BaseBucketTool.SYSUSER_COMPLAINT_PATH + UUIDGenerator.generate() + file.getOriginalFilename().substring(file.getOriginalFilename().lastIndexOf("."));
                baseBucketTool.upload(imgUrl, file,1);
                user.setAvatar(baseBucketTool.getDOMAIN() + imgUrl);
            }
            //将密码加密
            String password = user.getPassword();
            if(!StringUtil.isBlank(password)){
                user.setPassword(DESEncryptTools.encode(password));
            }
            user.setStatus(0);
            user.setId(UUIDGenerator.generate());
            user.setDeleted(0);
            user.setCreateTime(new Date());
            mongoTemplate.save(user);
            operationService.add(u, ip, "账号管理", "添加", "添加账号 ：" + user.getAccount());
        }
    }

    /**
     * @time: 2020/8/20 17:59
     * @author: Rock
     * @version 1.0
     */
    @Override
    public SysUser findById(Object id) {
        Query query = new Query(Criteria.where("_id").is(id));
        SysUser user = mongoTemplate.findOne(query, SysUser.class);
        userInfoHandle(user);
        return user;
    }

    /**
     * @param account
     * @time: 2020/11/3 18:35
     * @author: Rock
     * @version 1.0
     */
    public SysUser getByAccount(String account) {
        Query query = new Query(Criteria.where("account").is(account).and("deleted").is(0));
        SysUser user = mongoTemplate.findOne(query, SysUser.class);
        userInfoHandle(user);
        return user;
    }

    /**
     * @param [user]
     * @time: 2020/9/10 9:03
     * @author: Rock
     * @version 1.0
     */
    private void userInfoHandle(SysUser user) {
        if (user != null) {
            if (StringUtil.isNotBlank(user.getRoleId())) {
                user.setRole(roleService.findById(user.getRoleId()));
            }
            if (StringUtil.isNotBlank(user.getChannelAffiliationId())) {
                user.setChannelAff(channelAffiliationService.getById(user.getChannelAffiliationId()));
            }
            if (StringUtil.isNotBlank(user.getChannelAreaId())) {
                user.setChannelArea(channelAreaService.findById(user.getChannelAreaId()));
            }
        }
    }

    /**
     * @param [id, status]
     * @Description: 更新账号状态
     * @time: 2020/8/20 18:01
     * @author: Rock
     * @version 1.0
     */
    public void updateStatus(String id, Integer status, SysUser u, String ip) {
        Query query = new Query(Criteria.where("_id").is(id));
        Update update = new Update();
        update.set("status", status);
        update.set("update_time", new Date());
        mongoTemplate.updateFirst(query, update, SysUser.class);
        SysUser user = findById(id);
        operationService.add(u, ip, "账号管理", "编辑",
                "更新账号 :" + user.getAccount() + " 的状态为：" + (status == 0 ? "启用" : "禁用"));
    }

    /**
     * @Description: 更新删除状态
     * @time: 2020/8/20 18:03
     * @author: Rock
     * @version 1.0
     */
    public void updateDel(String id, SysUser u, String ip) {
        Query query = new Query(Criteria.where("_id").is(id));
        Update update = new Update();
        update.set("deleted", 1);
        update.set("update_time", new Date());
        mongoTemplate.updateFirst(query, update, SysUser.class);
        SysUser user = findById(id);
        operationService.add(u, ip, "账号管理", "删除", "删除账号 ：" + user.getAccount());
    }

    /**
     * @param [user]
     * @Description: 更新账号信息
     * @time: 2020/8/21 10:27
     * @author: Rock
     * @version 1.0
     */
    public void update(SysUser user, MultipartFile file, SysUser u, String ip) throws IOException {
        if (user != null) {
            Update update = new Update();
            if (user.getPassword() != null) {
                update.set("password", DESEncryptTools.encode(user.getPassword()));
            }
            if (user.getNickname() != null) {
                update.set("nickname", user.getNickname());
            }
            if (user.getRoleId() != null) {
                update.set("role_id", user.getRoleId());
            }
            if (user.getChannelAffiliationId() != null) {
                update.set("channel_affiliation_id", user.getChannelAffiliationId());
            }
            if (user.getType() != null) {
                update.set("type", user.getType());
            }
            if (user.getStatus() != null) {
                update.set("status", user.getStatus());
            }
            if (user.getUnbindNum() != null) {
                update.set("unbind_num", user.getUnbindNum());
            }
            if (user.getChannelAreaId() != null) {
                update.set("channel_area_id", user.getChannelAreaId());
            }
            if (file != null && !file.isEmpty()) {
                //上传头像处理
                String imgUrl = BaseBucketTool.SYSUSER_COMPLAINT_PATH + UUIDGenerator.generate() + file.getOriginalFilename().substring(file.getOriginalFilename().lastIndexOf("."));
                baseBucketTool.upload(imgUrl, file,1);
                update.set("avatar", baseBucketTool.getDOMAIN() + imgUrl);
            }
            update.set("update_time", new Date());
            this.updateById(user.getId(), update);
            operationService.add(u, ip, "账号管理", "编辑", "编辑账号 ：" + user.getAccount());
        }
    }

    /**
     * @param [id, account]
     * @time: 2020/9/3 16:06
     * @author: Rock
     * @version 1.0
     */
    public String checkAccount(String id, String account) {
        Query query = new Query(Criteria.where("deleted").is(0).and("account").is(account));
        SysUser user = mongoTemplate.findOne(query, SysUser.class);
        if (user != null) {
            if (StringUtils.isEmpty(id) || !id.equals(user.getId())) {
                return "账号已存在！";
            }
        }
        return "";
    }

    /**
     * @param [roleId]
     * @time: 2020/9/7 17:52
     * @author: Rock
     * @version 1.0
     */
    public Long countByRoleId(String roleId) {
        Query query = new Query(Criteria.where("deleted").is(0).and("role_id").regex(".*?" + roleId + ".*?", "i"));
        return mongoTemplate.count(query, SysUser.class);
    }

    /**
     * @param [channelAffiliationId]
     * @time: 2020/9/7 18:30
     * @author: Rock
     * @version 1.0
     */
    public Long countByChannelAffiliationId(String channelAffiliationId) {
        Query query = new Query(Criteria.where("deleted").is(0).and("channel_affiliation_id").regex(".*?" + channelAffiliationId + ".*?", "i"));
        return mongoTemplate.count(query, SysUser.class);
    }

    /**
     * @param id
     * @param unbindNum
     * @time: 2020/10/28 18:50
     * @author: Rock
     * @version 1.0
     */
    public void updateTodayUnbindNum(String id, int unbindNum) {
        Query query = new Query(Criteria.where("_id").is(id));
        SysUser user = mongoTemplate.findOne(query, SysUser.class);
        if (user != null) {
            Update update = new Update();
            String unbindDate = DateUtil.dateToStr(new Date(), DateUtil.FORMAT_4);
            update.set("unbind_date", unbindDate);
            if (unbindDate.equals(user.getUnbindDate())) {
                update.set("today_unbind_num", user.getTodayUnbindNum() == null ? unbindNum : user.getTodayUnbindNum() + unbindNum);
            } else {
                update.set("today_unbind_num", unbindNum);
            }
            mongoTemplate.updateFirst(query, update, SysUser.class);
        }
    }

}
